package com.yanqu.road.server.gameplayer.module.activity.commonwish;

import com.yanqu.road.dao.impl.activity.commonwish.CommonWishDataDaoImpl;
import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.activity.commonwish.CommonWishConfig;
import com.yanqu.road.entity.activity.commonwish.CommonWishDrawInfo;
import com.yanqu.road.entity.activity.commonwish.CommonWishUserData;
import com.yanqu.road.entity.enums.eGamePlayerEventType;
import com.yanqu.road.entity.enums.eLogMoneyType;
import com.yanqu.road.entity.enums.eSystemId;
import com.yanqu.road.entity.log.LogCommonWishDraw;
import com.yanqu.road.entity.log.LogCommonWishSelectBigReward;
import com.yanqu.road.entity.player.UserBagItem;
import com.yanqu.road.pb.activity.CommonWishProto;
import com.yanqu.road.server.GameServer;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.activity.ActivityModule;
import com.yanqu.road.server.gameplayer.module.base.GeneralModule;
import com.yanqu.road.server.gameplayer.module.player.BagModule;
import com.yanqu.road.server.gameplayer.module.player.CurrencyModule;
import com.yanqu.road.server.logic.activity.BaseActivityData;
import com.yanqu.road.server.logic.activity.condition.BaseActivityCondition;
import com.yanqu.road.server.manger.activity.ActivityMgr;
import com.yanqu.road.server.manger.activity.commonwish.CommonWishMgr;
import com.yanqu.road.server.manger.config.SystemOpenMgr;
import com.yanqu.road.server.manger.log.AutoLogMgr;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.server.protocol.Protocol;
import com.yanqu.road.utils.RandomHelper;
import com.yanqu.road.utils.date.DateHelper;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.property.PropertyHelper;
import com.yanqu.road.utils.string.StringUtils;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;

public class CommonWishModule extends GeneralModule {

    Map<Integer, CommonWishUserData> userDataMap = new ConcurrentHashMap<>();

    Random random = new Random();

    public CommonWishModule(GamePlayer player) {
        super(player);
    }

    @Override
    public boolean loadData() {

        List<Integer> activityList = new ArrayList<>();
        for (Map.Entry<Integer, CommonWishConfig> entry : CommonWishMgr.getConfigMap().entrySet()) {
            CommonWishConfig config = entry.getValue();
            ActivityInfo activityInfo = config.getActivityInfo();
            if (ActivityMgr.activityInShowTime(activityInfo)) {
                activityList.add(activityInfo.getActivityId());
            }
        }
        if(activityList.size() > 0) {
            userDataMap = new CommonWishDataDaoImpl().getCommonWishUserData(activityList, player.getUserId());
        }
        return true;
    }

    @Override
    public boolean afterLoadData() {
        return true;
    }

    @Override
    public boolean saveData() {
        for (Map.Entry<Integer, CommonWishUserData> entry : userDataMap.entrySet()) {
            CommonWishUserData userData = entry.getValue();
            if (userData.isInsertOption()) {
                new CommonWishDataDaoImpl().add(userData);
            }else if (userData.isUpdateOption()){
                new CommonWishDataDaoImpl().update(userData);
            }
        }
        return true;
    }

    @Override
    public void afterLogin() {

        if (!SystemOpenMgr.systemOpen(player, eSystemId.CommonWishDraw.getValue())) {
            return;
        }

        syncConfig();

        initUserData();

        resetOneDay();

        syncUserData();

    }

    public void syncConfig() {
        for (Map.Entry<Integer, CommonWishConfig> entry : CommonWishMgr.getConfigMap().entrySet()) {
            CommonWishConfig config = entry.getValue();
            if (config == null || !ActivityMgr.activityInShowTime(config.getActivityInfo())) {
                continue;
            }

            CommonWishProto.CommonWishConfigDataSyncMsg.Builder configSync = CommonWishProto.CommonWishConfigDataSyncMsg.newBuilder();
            configSync.addAllDraw(CommonWishPb.buildDrawTemp(config.getDrawInfoList(), player.getLanguage()));
            configSync.setActivityId(entry.getKey());
            player.sendPacket(Protocol.U_COMMON_WISH_SYNC_CONFIG, configSync);
        }
    }

    public synchronized void initUserData() {
        // 系统未解锁
        if (!SystemOpenMgr.systemOpen(player, eSystemId.CommonWishDraw.getValue())) {
            return;
        }


        for (Map.Entry<Integer, CommonWishConfig> entry : CommonWishMgr.getConfigMap().entrySet()) {

            CommonWishConfig config = entry.getValue();
            // 没有活动
            if (!ActivityMgr.activityInShowTime(config.getActivityInfo())) {
                continue;
            }

            ActivityInfo activityInfo = config.getActivityInfo();
            if(!userDataMap.containsKey(activityInfo.getActivityId())) {
                CommonWishUserData tmpUserData = new CommonWishUserData();
                tmpUserData.setActivityId(activityInfo.getActivityId());
                tmpUserData.setUserId(getUserId());
                tmpUserData.setInsertOption();
                tmpUserData.setDrawRound(1);
                tmpUserData.setResetTime(DateHelper.getTodayZeroTime());
                userDataMap.put(activityInfo.getActivityId(), tmpUserData);
            }
        }
    }

    public void syncUserData() {

        CommonWishProto.CommonWishUserDataSyncMsg.Builder syncMsg = CommonWishProto.CommonWishUserDataSyncMsg.newBuilder();

        for (Map.Entry<Integer, CommonWishConfig> entry : CommonWishMgr.getConfigMap().entrySet()) {

            CommonWishConfig config = entry.getValue();
            if (!ActivityMgr.activityInShowTime(config.getActivityInfo())) {
                continue;
            }

            CommonWishUserData userData = userDataMap.get(config.getActivityInfo().getActivityId());
            if(userData == null){
                continue;
            }

            CommonWishProto.CommonWishUserDataTemp.Builder builder = CommonWishPb.buildUserData(userData);
            builder.setActivityId(entry.getKey());
            syncMsg.addUserData(builder);

        }

        player.sendPacket(Protocol.U_COMMON_WISH_SYNC_USER_DATA, syncMsg);

    }

    public boolean resetOneDay(){

        for (Map.Entry<Integer, CommonWishConfig> entry : CommonWishMgr.getConfigMap().entrySet()) {
            CommonWishConfig config = entry.getValue();
            try{
                // 没有活动
                if (!ActivityMgr.activityInTime(config.getActivityInfo())) {
                    continue;
                }

                CommonWishUserData userData = userDataMap.get(config.getActivityInfo().getActivityId());
                if(userData == null){
                    continue;
                }

            }catch (Exception e){

            }
        }

        return true;
    }

    /**
     * 碎片点亮
     */
    public int lightUp(int position, int activityId) {

        CommonWishConfig config = CommonWishMgr.getCommonWishConfig(activityId);
        if(config == null){
            return GameErrorCode.E_ACTIVITY_OVER_TIME;
        }

        CommonWishUserData userData = userDataMap.get(config.getActivityInfo().getActivityId());

        if(userData == null){
            return GameErrorCode.E_SYSTEM_NO_OPEN;
        }


        if(userData.getPositionList().contains(position)){
            return GameErrorCode.E_COMMON_WISH_CAN_NOT_REPEATED_LIGHT_UP;
        }

        String consume = config.getPiceItemId() + "=1";
        if(!player.getModule(CurrencyModule.class).removeCurrency(PropertyHelper.parseStringToProperty(consume), eLogMoneyType.CommonWishDraw, eLogMoneyType.CommonWishDrawLightUpConsume)){
            return GameErrorCode.E_BAG_ITEM_NO_ENOUGH;
        }

        userData.getPositionList().add(position);
        userData.setUpdateOption();

        player.notifyListener(eGamePlayerEventType.CommonWishPieceUnLock.getValue(), userData.getPositionList().size());

        //进度大奖是否可以領取
        String reward = "";
        BaseActivityData baseActivityData = player.getModule(ActivityModule.class).getBaseActivityData(userData.getActivityId());
        if(baseActivityData != null){
            int conditionId = 0;
            BaseActivityCondition activityCondition = null;
            for (BaseActivityCondition baseActivityCondition : baseActivityData.getBaseActivityConditionList()) {
                if(baseActivityCondition.getConditionType() == eGamePlayerEventType.CommonWishPieceUnLock.getValue()){
                    if(baseActivityCondition.getConditionId() > conditionId){
                        activityCondition = baseActivityCondition;
                        conditionId = baseActivityCondition.getConditionId();
                    }
                }
            }
            if(activityCondition != null){
                if(activityCondition.isCompleted(player)){
                    reward = activityCondition.getReward();
                }
            }
        }


        CommonWishProto.CommonWishLightUpRespMsg.Builder respMsg = CommonWishProto.CommonWishLightUpRespMsg.newBuilder().setRet(0);
        CommonWishProto.CommonWishUserDataTemp.Builder builder = CommonWishPb.buildUserData(userData);
        builder.setActivityId(userData.getActivityId());
        respMsg.setReward(reward);
        respMsg.setUserData(builder);
        player.sendPacket(Protocol.U_COMMON_WISH_LIGHT_UP, respMsg);

        return 0;
    }

    /**
     * 设置大奖
     */
    public int setBigReward(int index, int activityId) {

        CommonWishConfig config = CommonWishMgr.getCommonWishConfig(activityId);
        if(config == null){
            return GameErrorCode.E_ACTIVITY_OVER_TIME;
        }

        CommonWishUserData userData = userDataMap.get(config.getActivityInfo().getActivityId());

        if(userData == null){
            return GameErrorCode.E_SYSTEM_NO_OPEN;
        }


        if(!isLeftBigReward(userData, config)){
            return GameErrorCode.E_COMMON_WISH_NO_BIG_REWARD;
        }

        if(index < 0 || index >= config.getPoolItemList().size()){
            return GameErrorCode.E_REQUEST_ARGUMENT_ERROR;
        }

        String newReward = config.getPoolItemList().get(index);

        //如果有进度，不让重新设置
        if(userData.getDrawOpp() > 0){
            return GameErrorCode.E_COMMON_WISH_HAD_SELECTED_BIG_REWARD;
        }

        int maxTimes = config.getPoolTimesList().get(index);
        int nowTimes = userData.getBigSelectMap().getOrDefault(index, 0);

        if(nowTimes >= maxTimes){
            return GameErrorCode.E_COMMON_WISH_BIG_REWARD_SELECT_LIMIT;
        }

        userData.setBigReward(newReward);

        CommonWishProto.CommonWishBigRewardSetRespMsg.Builder respMsg = CommonWishProto.CommonWishBigRewardSetRespMsg.newBuilder().setRet(0);
        CommonWishProto.CommonWishUserDataTemp.Builder builder = CommonWishPb.buildUserData(userData);
        builder.setActivityId(userData.getActivityId());
        respMsg.setUserData(builder);
        player.sendPacket(Protocol.U_COMMON_WISH_BIG_REWARD, respMsg);

        //日志
        AutoLogMgr.add(new LogCommonWishSelectBigReward(userData.getActivityId(),
                userData.getUserId(),
                userData.getDrawRound(),
                userData.getBigReward()));

        return 0;
    }

    /**
     * 是否还有大奖可以选
     */
    public boolean isLeftBigReward(CommonWishUserData userData, CommonWishConfig config){
        for (int i = 0; i < config.getPoolTimesList().size(); i++) {
            int times = userData.getBigSelectMap().getOrDefault(i, 0);
            if(times < config.getPoolTimesList().get(i)){
                return true;
            }
        }
        return false;
    }

    /**
     * 取宝 抽奖
     */
    public int draw(int type, int activityId) {

        CommonWishConfig config = CommonWishMgr.getCommonWishConfig(activityId);
        if(config == null){
            return GameErrorCode.E_ACTIVITY_OVER_TIME;
        }

        CommonWishUserData userData = userDataMap.get(config.getActivityInfo().getActivityId());

        if(userData == null){
            return GameErrorCode.E_SYSTEM_NO_OPEN;
        }

        if(StringUtils.isNullOrEmpty(userData.getBigReward()) && isLeftBigReward(userData, config)){
            return GameErrorCode.E_COMMON_WISH_NO_SELECTED_BIG_REWARD;
        }
        int times = 1;
        if(type == 1){
            times = 10;
        }

        if(type == 1 && userData.getScore() < config.getTenDrawScoreLimit()){
            return GameErrorCode.E_COMMON_WISH_TEN_DRAW_LOCK;
        }

//        if (type == 2 && userData.getTotalDrawTimes() < config.getQuickUseNum()) {
//            return GameErrorCode.E_COMMON_WISH_ONE_KEY_DRAW_LOCK;
//        }

        //是否达到机缘值最大，不能超过
        int leftVal = config.getDrawOppMax() - userData.getDrawOpp();
        int needTimes = leftVal / config.getDrawOppAdd() + 1;

        if (type == 2 || needTimes < times) {
            times = needTimes;
        }

        //消耗是否足够
        String consume = config.getDrawItemId() + "=" + times;

        if(!player.getModule(CurrencyModule.class).currencyIsEnough(PropertyHelper.parseStringToProperty(consume))){

            //如果是十连，消耗掉所有道具,或者一键
            if(times > 1 || type == 2){
                UserBagItem bagItem = player.getModule(BagModule.class).getUserBagItem(config.getDrawItemId());
                if(bagItem == null || bagItem.getNum() == 0){
                    return GameErrorCode.E_BAG_ITEM_NO_ENOUGH;
                }
                if(bagItem.getNum() > Integer.MAX_VALUE){
                    return GameErrorCode.E_BAG_ITEM_NO_ENOUGH;
                }
                times = (int)bagItem.getNum();
                consume = config.getDrawItemId() + "=" + times;
            }else {
                return GameErrorCode.E_BAG_ITEM_NO_ENOUGH;
            }
        }

        int realTimes = 0;
        int tempOppVal = userData.getDrawOpp();
        int drawRound = userData.getDrawRound();
        int drawTimes = userData.getDrawTimes();

        CommonWishProto.CommonWishUploadDrawNoticeMsg.Builder noticeUploadBuilder = CommonWishProto.CommonWishUploadDrawNoticeMsg.newBuilder();
        boolean getBigReward = false;
        Property reward = new Property();
        List<String> timeRewardList = new ArrayList<>();
        //获得积分
        for (int i = 0; i < times; i++) {
            int bigWeight = config.getBigRewardWeight(tempOppVal);

            if((random.nextInt(1000) < bigWeight || tempOppVal + config.getDrawOppAdd() > config.getDrawOppMax()) && !StringUtils.isNullOrEmpty(userData.getBigReward())){
                reward.addProperty(PropertyHelper.parseStringToProperty(userData.getBigReward()));
                timeRewardList.add(userData.getBigReward());
                getBigReward = true;
                realTimes++;
                addNoticeMsg(noticeUploadBuilder, userData.getBigReward());
                break;
            }else {
                CommonWishDrawInfo info = getRandomNormalReward(userData, config, random);
                reward.addProperty(PropertyHelper.parseStringToProperty(info.getReward()));
                timeRewardList.add(info.getReward());
                tempOppVal += config.getDrawOppAdd();
                realTimes++;
                if(info.getIsNotice() == 1){
                    addNoticeMsg(noticeUploadBuilder, info.getReward());
                }
            }
        }

        consume = config.getDrawItemId() + "=" + realTimes;

        if(!player.getModule(CurrencyModule.class).removeCurrency(PropertyHelper.parseStringToProperty(consume), eLogMoneyType.CommonWishDraw, eLogMoneyType.CommonWishDrawDrawConsume)){
            return GameErrorCode.E_BAG_ITEM_NO_ENOUGH;
        }

        //是否达到机缘值上限
        if(getBigReward){
            int index = getBigRewardIndex(userData.getBigReward(), config);
            int old = userData.getBigSelectMap().getOrDefault(index, 0);
            userData.getBigSelectMap().put(index, old + 1);
            userData.setBigReward("");
            userData.setDrawOpp(0);
            //轮次+1
            userData.setDrawRound(userData.getDrawRound() + 1);
            userData.setDrawTimes(0);
        }else {
            userData.setDrawOpp(userData.getDrawOpp() + realTimes * config.getDrawOppAdd());
            userData.setDrawTimes(userData.getDrawTimes() + realTimes);
        }
        userData.setAllDrawOpp(userData.getAllDrawOpp() + realTimes * config.getDrawOppAdd());
        userData.setTotalDrawTimes(userData.getTotalDrawTimes() + realTimes);

        if(ActivityMgr.activityInTime(config.getActivityInfo())) {
            //积分
            userData.setScore(userData.getScore() + config.getDrawScoreGet() * realTimes);
            reward.addProperty(config.getScoreItemId(), BigInteger.valueOf(config.getDrawScoreGet() * realTimes));
        }else {
            CommonWishMgr.getLogger().info("player {} activityId {} InRewardPeriod draw times {}", player.getUserId(), userData.getActivityId(), realTimes);
        }

        player.getModule(CurrencyModule.class).addCurrency(reward, eLogMoneyType.CommonWishDraw, eLogMoneyType.CommonWishDrawDrawReward);

        player.notifyListener(eGamePlayerEventType.CommonWishScoreRank.getValue(), userData.getScore());
        player.notifyListener(eGamePlayerEventType.CommonWishTotalDraw.getValue(), userData.getTotalDrawTimes());

        CommonWishProto.CommonWishDrawRespMsg.Builder respMsg = CommonWishProto.CommonWishDrawRespMsg.newBuilder().setRet(0);
        respMsg.setReward(PropertyHelper.parsePropertyToString(reward));
        respMsg.addAllTimesReward(timeRewardList);
        CommonWishProto.CommonWishUserDataTemp.Builder builder = CommonWishPb.buildUserData(userData);
        builder.setActivityId(userData.getActivityId());
        respMsg.setUserData(builder);
        player.sendPacket(Protocol.U_COMMON_WISH_DRAW, respMsg);

        if(noticeUploadBuilder.getNoticeCount() > 0){
            noticeUploadBuilder.setActivityId(config.getActivityInfo().getActivityId());
            player.sendPacket(Protocol.C_COMMON_WISH_UPLOAD_DRAW_NOTICE, noticeUploadBuilder);
        }

        //日志
        AutoLogMgr.add(new LogCommonWishDraw(userData.getActivityId(),
                userData.getUserId(),
                drawRound,
                drawTimes + realTimes,
                realTimes,
                PropertyHelper.parsePropertyToString(reward),
                userData.getDrawOpp() == 0, config.getActivityInfo().getChildType()));

        return 0;
    }

    private void addNoticeMsg(CommonWishProto.CommonWishUploadDrawNoticeMsg.Builder noticeUploadBuilder, String reward) {
        CommonWishProto.CommonWishNoticeMsg.Builder builder = CommonWishProto.CommonWishNoticeMsg.newBuilder();
        builder.setServerId(GameServer.getInstance().getServerId());
        builder.setNickName(player.getUserInfo().getNickName());
        builder.setTime(System.currentTimeMillis());
        builder.setValue(0);
        builder.setReward(reward);
        noticeUploadBuilder.addNotice(builder);
    }

    private int getBigRewardIndex(String bigReward, CommonWishConfig config) {
        int index = -1;
        for (int i = 0; i < config.getPoolItemList().size(); i++) {
            if(bigReward.equals(config.getPoolItemList().get(i))){
                return i;
            }
        }

        return index;
    }

    public CommonWishDrawInfo getRandomNormalReward(CommonWishUserData userData, CommonWishConfig config, Random random){
        List<String> rewardList = new ArrayList<>();
        List<Integer> weightList = new ArrayList<>();
        List<CommonWishDrawInfo> infoList = new ArrayList<>();
        for (CommonWishDrawInfo info : config.getDrawInfoList()) {
            if(info.getWeight() <= 0){
                continue;
            }
            rewardList.add(info.getReward());
            weightList.add(info.getWeight());
            infoList.add(info);
        }
        int index = RandomHelper.getRandomIndexByWeight(weightList, random);
        return infoList.get(index);
    }

    public Map<Integer, CommonWishUserData> getUserDataMap() {
        return userDataMap;
    }

}
